package com.jackie.easyble.ui.activities

import android.bluetooth.le.AdvertiseSettings
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.view.View
import android.widget.AdapterView
import android.widget.CompoundButton
import androidx.recyclerview.widget.LinearLayoutManager
import com.chad.library.adapter4.BaseQuickAdapter
import com.jackie.easyble.R
import com.jackie.easyble.databinding.ActivitySendBroadcastBinding
import com.jackie.easyble.ui.adapter.AdvertiseUuidRecyclerViewAdapter
import com.jackie.easyble.ui.adapter.FixedAdvertiseDataRecyclerViewAdapter
import com.jackie.easyble.ui.dialogs.AddAdvertiseDataDialog
import com.jackie.easyble.ui.dialogs.AddAdvertiseUuidDialog
import com.sscl.baselibrary.activity.BaseDataBindingAppCompatActivity
import com.sscl.baselibrary.utils.BaseManager
import com.sscl.baselibrary.utils.DefaultItemDecoration
import com.sscl.baselibrary.utils.ToastUtil
import com.sscl.easyble.BleManager
import com.sscl.easyble.advertise.AdvertiseUuid
import com.sscl.easyble.advertise.FixedAdvertiseData
import com.sscl.easyble.enums.advertise.AdvertiseMode
import com.sscl.easyble.enums.advertise.BleAdvertiseTxPowerLevel
import com.sscl.easyble.interfaces.advertise.BleAdvertiseCallback

/**
 * 发送BLE广播数据
 */
class SendBroadcastActivity : BaseDataBindingAppCompatActivity<ActivitySendBroadcastBinding>() {

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *
     * 常量属性
     *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    private val advertiseCallback = object : BleAdvertiseCallback {

        override fun onStartSuccess(settingsInEffect: AdvertiseSettings) {
        }

        /**
         * 广播超时
         */
        override fun timeout() {
            ToastUtil.toastShort(this@SendBroadcastActivity, "广播到期")
            binding.advertiseOperatorBtn.setText(R.string.start_advertise)
        }

        /**
         * Callback when advertising could not be started.
         *
         * @param errorCode Error code (see ADVERTISE_FAILED_* constants) for advertising start
         * failures.
         */
        override fun onStartFailure(errorCode: Int) {
            ToastUtil.toastShort(this@SendBroadcastActivity, "广播失败，错误码：$errorCode")
            binding.advertiseOperatorBtn.setText(R.string.start_advertise)
        }
    }

    private val onAdvertiseUuidItemLongClickListener =
        BaseQuickAdapter.OnItemLongClickListener<AdvertiseUuid> { adapter, view, position ->

            when (adapter) {
                advertiseUuidRecyclerViewAdapter -> {
                    bleAdvertiser.removeAdvertiseServiceUuidData(
                        advertiseUuidRecyclerViewAdapter.getItem(
                            position
                        ) ?: return@OnItemLongClickListener false
                    )
                }

                scanResponseUuidRecyclerViewAdapter -> {
                    bleAdvertiser.removeAdvertiseServiceUuidData(
                        scanResponseUuidRecyclerViewAdapter.getItem(
                            position
                        ) ?: return@OnItemLongClickListener false
                    )
                }
            }
            adapter.removeAt(position)
            true
        }
    private val onAdvertiseDataItemLongClickListener =
        BaseQuickAdapter.OnItemLongClickListener<FixedAdvertiseData> { adapter, view, position ->
            when (adapter) {
                advertiseDataRecyclerViewAdapter -> {
                    bleAdvertiser.removeAdvertiseData(
                        advertiseDataRecyclerViewAdapter.getItem(
                            position
                        ) ?: return@OnItemLongClickListener false
                    )
                }

                scanResponseRecyclerViewAdapter -> {
                    bleAdvertiser.removeScanResponseData(
                        scanResponseRecyclerViewAdapter.getItem(
                            position
                        ) ?: return@OnItemLongClickListener false
                    )
                }
            }
            adapter.removeAt(position)
            true
        }

    /**
     * BLE 广播实例
     */
    private val bleAdvertiser = BleManager.getAdvertiserInstance()

    /**
     * 点击事件监听器
     */
    private val onClickListener = View.OnClickListener {

        when (it) {
            binding.addAdvertiseDataBtn -> {
                showAddAdvertiseDataDialog()
            }

            binding.addAdvertiseUuidBtn -> {
                showAddAdvertiseUuidDialog()
            }

            binding.addScanResponseDataBtn -> {
                showAddScanResponseDataDialog()
            }

            binding.addScanResponseUuidBtn -> {
                showAddScanResponseUuidDialog()
            }


            binding.advertiseOperatorBtn -> {
                if (bleAdvertiser.isAdvertising) {
                    bleAdvertiser.stopAdvertise()
                    binding.advertiseOperatorBtn.setText(R.string.start_advertise)
                } else {
                    val timeoutString = binding.advertiseTimeoutEt.text.toString()
                    if (timeoutString.isEmpty()) {
                        ToastUtil.toastShort(this@SendBroadcastActivity, R.string.timeout_empty)
                        return@OnClickListener
                    }
                    val timeout = timeoutString.toInt()
                    bleAdvertiser.setAdvertiseTimeoutMillis(timeout)
                    bleAdvertiser.startAdvertise()
                    binding.advertiseOperatorBtn.setText(R.string.stop_advertise)
                }
            }
        }
    }

    /**
     * 数据选择回调
     */
    private val onItemSelectedListener = object : AdapterView.OnItemSelectedListener {

        override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
            when (parent) {
                binding.advertiseModeRsp -> {
                    bleAdvertiser.setAdvertiseMode(AdvertiseMode.entries[position])
                }

                binding.advertiseTxPowerRsp -> {
                    bleAdvertiser.setAdvertiseTxPowerLevel(BleAdvertiseTxPowerLevel.entries[position])
                }
            }
        }

        override fun onNothingSelected(parent: AdapterView<*>?) {
            BaseManager.newThreadFactory()
        }

    }

    /**
     * 选中状态变化的回调
     */
    private val onCheckedChangedListener =
        CompoundButton.OnCheckedChangeListener { buttonView, isChecked ->
            when (buttonView) {
                binding.advertiseConnectableCb -> {
                    bleAdvertiser.setConnectable(isChecked)
                }

                binding.advertiseDiscoverableCb -> {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
                        bleAdvertiser.setDiscoverable(isChecked)
                    }
                }

                binding.advertiseIncludeTxPowerCb -> {
                    bleAdvertiser.setAdvertiseDataIncludeTxPowerLevel(isChecked)
                }

                binding.advertiseIncludeDeviceNameCb -> {
                    bleAdvertiser.setAdvertiseDataIncludeDeviceName(isChecked)
                }

                binding.scanResponseIncludeTxPowerCb -> {
                    bleAdvertiser.setScanResponseDataIncludeTxPowerLevel(isChecked)
                }

                binding.scanResponseIncludeDeviceNameCb -> {
                    bleAdvertiser.setScanResponseDataIncludeDeviceName(isChecked)
                }
            }
        }

    private val advertiseDataRecyclerViewAdapter = FixedAdvertiseDataRecyclerViewAdapter()
    private val advertiseUuidRecyclerViewAdapter = AdvertiseUuidRecyclerViewAdapter()

    private val scanResponseRecyclerViewAdapter = FixedAdvertiseDataRecyclerViewAdapter()
    private val scanResponseUuidRecyclerViewAdapter = AdvertiseUuidRecyclerViewAdapter()

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *
     * 实现方法
     *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    /**
     * 设置布局
     */
    override fun setLayout(): Int {
        return R.layout.activity_send_broadcast
    }

    /**
     * 标题栏的返回按钮被按下的时候回调此方法
     */
    override fun titleBackClicked(): Boolean {
        return false
    }

    /**
     * 在设置布局之前需要进行的操作
     */
    override fun doBeforeSetLayout() {

    }

    /**
     * 设置DataBinding
     * 可在此处设置binding的viewModel或观察者等操作
     */
    override fun setBinding() {

    }

    /**
     * 在设置布局之后，进行其他操作之前，所需要初始化的数据
     */
    override fun doBeforeInitOthers() {

    }

    /**
     * 初始化控件数据
     */
    override fun initViewData(savedInstanceState: Bundle?) {
        binding.advertiseDiscoverableCb.isEnabled =
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE
        initAdvertiseDataRvData()
        initAdvertiseUuidRvData()
        initScanResponseRvData()
        initScanResponseUuidRvData()
    }

    /**
     * 初始化其他数据
     */
    override fun initOtherData() {

    }

    /**
     * 初始化事件
     */
    override fun initEvents() {
        binding.advertiseModeRsp.onItemSelectedListener = onItemSelectedListener
        binding.advertiseTxPowerRsp.onItemSelectedListener = onItemSelectedListener

        binding.advertiseConnectableCb.setOnCheckedChangeListener(onCheckedChangedListener)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
            binding.advertiseDiscoverableCb.setOnCheckedChangeListener(onCheckedChangedListener)
        }
        binding.advertiseIncludeTxPowerCb.setOnCheckedChangeListener(onCheckedChangedListener)
        binding.advertiseIncludeDeviceNameCb.setOnCheckedChangeListener(onCheckedChangedListener)
        binding.scanResponseIncludeTxPowerCb.setOnCheckedChangeListener(onCheckedChangedListener)
        binding.scanResponseIncludeDeviceNameCb.setOnCheckedChangeListener(onCheckedChangedListener)

        advertiseDataRecyclerViewAdapter.setOnItemLongClickListener(
            onAdvertiseDataItemLongClickListener
        )
        scanResponseRecyclerViewAdapter.setOnItemLongClickListener(
            onAdvertiseDataItemLongClickListener
        )

        advertiseUuidRecyclerViewAdapter.setOnItemLongClickListener(
            onAdvertiseUuidItemLongClickListener
        )
        scanResponseUuidRecyclerViewAdapter.setOnItemLongClickListener(
            onAdvertiseUuidItemLongClickListener
        )

        binding.addAdvertiseDataBtn.setOnClickListener(onClickListener)
        binding.addAdvertiseUuidBtn.setOnClickListener(onClickListener)
        binding.addScanResponseDataBtn.setOnClickListener(onClickListener)
        binding.addScanResponseUuidBtn.setOnClickListener(onClickListener)
        binding.advertiseOperatorBtn.setOnClickListener(onClickListener)

        bleAdvertiser.setAdvertiseCallback(advertiseCallback)
    }

    /**
     * 在最后进行的操作
     */
    override fun doAfterAll() {
    }

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *
     * 重写方法
     *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    override fun onDestroy() {
        super.onDestroy()
        BleManager.releaseAdvertiserInstance()
    }

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *
     * 私有方法
     *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    /**
     * 显示添加广播数据对话框
     */
    private fun showAddAdvertiseDataDialog() {
        AddAdvertiseDataDialog(this) {
            advertiseDataRecyclerViewAdapter.add(it)
            bleAdvertiser.addAdvertiseData(it)
        }.show()
    }

    /**
     * 显示添加广播UUID对话框
     */
    private fun showAddAdvertiseUuidDialog() {
        AddAdvertiseUuidDialog(this) {
            advertiseUuidRecyclerViewAdapter.add(it)
            bleAdvertiser.addAdvertiseServiceUuidData(it)
        }.show()
    }

    /**
     * 显示添加扫描响应数据对话框
     */
    private fun showAddScanResponseDataDialog() {
        AddAdvertiseDataDialog(this) {
            scanResponseRecyclerViewAdapter.add(it)
            bleAdvertiser.addScanResponseData(it)
        }.show()
    }

    /**
     * 显示添加扫描响应UUID对话框
     */
    private fun showAddScanResponseUuidDialog() {
        AddAdvertiseUuidDialog(this) {
            scanResponseUuidRecyclerViewAdapter.add(it)
            bleAdvertiser.addScanResponseServiceUuidData(it)
        }.show()
    }

    /**
     * 初始化广播数据RecyclerView数据
     */
    private fun initAdvertiseDataRvData() {
        binding.advertiseDataRv.layoutManager = LinearLayoutManager(this)
        binding.advertiseDataRv.adapter = advertiseDataRecyclerViewAdapter
        binding.advertiseDataRv.addItemDecoration(DefaultItemDecoration.newLine(Color.GRAY))
    }

    /**
     * 初始化广播UUID数据RecyclerView数据
     */
    private fun initAdvertiseUuidRvData() {
        binding.advertiseUuidRv.layoutManager = LinearLayoutManager(this)
        binding.advertiseUuidRv.adapter = advertiseUuidRecyclerViewAdapter
        binding.advertiseUuidRv.addItemDecoration(DefaultItemDecoration.newLine(Color.GRAY))
    }

    /**
     * 初始化扫描响应数据RecyclerView数据
     */
    private fun initScanResponseRvData() {
        binding.scanResponseDataRv.layoutManager = LinearLayoutManager(this)
        binding.scanResponseDataRv.adapter = scanResponseRecyclerViewAdapter
        binding.scanResponseDataRv.addItemDecoration(DefaultItemDecoration.newLine(Color.GRAY))
    }

    /**
     * 初始化扫描响应UUID数据RecyclerView数据
     */
    private fun initScanResponseUuidRvData() {
        binding.scanResponseUuidRv.layoutManager = LinearLayoutManager(this)
        binding.scanResponseUuidRv.adapter = scanResponseUuidRecyclerViewAdapter
        binding.scanResponseUuidRv.addItemDecoration(DefaultItemDecoration.newLine(Color.GRAY))
    }

}